//
// Copyright (c) 2009 All Right Reserved
//
// vl
//
// 2009-01-01
// Contains ...
using System;
using System.Text;
using JetBrains.Annotations;
namespace LargoCommon.Music
{
///
/// Note Length.
///
public class NoteLength {
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The given tuple number.
/// The given denominator.
/// The given number of dots.
/// The given tuple position.
public NoteLength(TupleNumber givenTupleNumber, MusicalDenominator givenDenominator, int givenNumberOfDots, TuplePosition givenTuplePosition) {
this.TupleNumber = givenTupleNumber;
this.Denominator = givenDenominator;
this.NumberOfDots = givenNumberOfDots;
this.TuplePosition = givenTuplePosition;
}
///
/// Initializes a new instance of the class.
///
/// The ticks.
/// The whole note ticks.
public NoteLength(int ticks, int wholeNoteTicks) {
this.TupleNumber = TupleNumber.Single;
this.NumberOfDots = 0;
if (ticks == 0) {
return;
}
//// var smallestLength = (float)wholeNoteTicks / 128;
//// var denominator = 1;
double baseTicks;
if (ticks > wholeNoteTicks) {
this.Denominator = MusicalDenominator.Whole;
//// baseTicks = wholeNoteTicks;
return;
}
else {
var s = wholeNoteTicks / ticks;
var r = Math.Log(s) / Math.Log(2);
var cr = Math.Ceiling(r);
if (cr > 7) {
cr = 7;
}
double dr = Math.Pow(2, cr);
this.Denominator = (MusicalDenominator)dr;
baseTicks = Math.Round(wholeNoteTicks / dr);
}
var q = ticks / baseTicks;
if (q > 1.4) {
this.NumberOfDots = 1;
}
if (q > 1.7) {
this.NumberOfDots = 2;
}
//// Temporarily - the aim is not register very short pauses ...
if (this.Denominator == MusicalDenominator.D128Th) {
this.Denominator = MusicalDenominator.None;
}
}
#endregion
#region Properties
///
/// Gets the Denominator.
///
/// Property description.
public MusicalDenominator Denominator { get; }
///
/// Gets the number of dots.
///
///
/// The number of dots.
///
public int NumberOfDots { get; }
///
/// Gets the tuple.
///
///
/// The tuple.
///
public TuplePosition TuplePosition { get; }
///
/// Gets or sets a value indicating whether [include pause]. Staccato...
///
///
/// true if [include pause]; otherwise, false.
///
public bool IncludePause { get; set; }
///
/// Gets the tuple.
///
///
/// The tuple.
///
// ReSharper disable once UnusedAutoPropertyAccessor.Local
private TupleNumber TupleNumber { [UsedImplicitly] get; }
#endregion
#region Factory methods
///
/// Gets the length of the note.
///
/// The ticks.
/// The pause ticks.
/// The whole note ticks.
/// Returns value.
public static NoteLength GetNoteLength(int ticks, int pauseTicks, int wholeNoteTicks) {
//// if (ticks == 53 && pauseTicks == 120) { pauseTicks++; pauseTicks--; }
if (pauseTicks == 0) {
return new NoteLength(ticks, wholeNoteTicks);
}
var pauseLength = new NoteLength(pauseTicks, wholeNoteTicks);
bool auxiliaryPause = (pauseLength.Denominator == MusicalDenominator.None)
|| ((pauseLength.Denominator >= MusicalDenominator.Sixteenth) && pauseTicks < 1.3 * ticks);
NoteLength nl;
// ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
if (auxiliaryPause) {
nl = new NoteLength(ticks + pauseTicks, wholeNoteTicks) { IncludePause = true };
}
else {
//// if (ticks == 1) { pauseTicks++; pauseTicks--; }
nl = new NoteLength(ticks, wholeNoteTicks) { IncludePause = false };
}
return nl;
}
#endregion
#region String representation
///
/// Returns a that represents this instance.
///
///
/// A that represents this instance.
///
public override string ToString() {
StringBuilder sb = new StringBuilder();
sb.Append(this.Denominator);
sb.AppendFormat(" {0} dots ", this.NumberOfDots);
sb.Append(this.TuplePosition);
return sb.ToString();
}
#endregion
}
}